#include "nettchannel.h"

#include <time.h>
#ifdef WIN32
#define usleep(x) Sleep(x)
#endif
#include "pfunc.h"
#include "datadef.h"
#include "business_def.h"
#include "socketclient.h"
#include "Log.h"

NetTChannel::NetTChannel(int tid_)
    : TranChannel(tid_)
{
    init(tid_);
}

NetTChannel::~NetTChannel()
{
    running = false;
}

void* NetTChannel::run()
{
    if (NULL == ptr_client) 
	{
		CLogger::createInstance()->Log(MsgError,
			"NetTChannel start fail for ptr_client is NULL"
			",[%s %s %d]!"
			, __FILE__, __FUNCTION__, __LINE__);
		return 0;
	}
	while(running)
	{
		if (ptr_client->isConnect()) 
        {
            //读取数据
            read();
			//进行数据写入
			wtite();
		}else{
            ptr_client->disConnect();
            bool linkf = ptr_client->connect();
			if (!linkf)
			{
				sleep(15);  //连接不上,等待15秒
			}else{
                WriteDataS->clear();
            }
		}
		usleep(1);
	}
    return NULL;
}

void NetTChannel::init(int tid_)
{
    running = true;
    BusinessDef *ptrBDef = BusinessDef::getInstance();
    if(ptrBDef->getNetInfoByTID(tid_,netargs))
    {
        ptr_client = new SocketClinet(netargs.ip,netargs.port);
    }
    heartBeatWrite = static_cast<unsigned int>(time(NULL));
}

void NetTChannel::read()
{
    //读取帧数据
    switch (netargs.type)
    {
    case 1:
    {
        //数据有特定帧头和结尾,做分帧处理
        int ret = ptr_client->Read(rdc_data);
        if (ret > 0)
        {
            unsigned char * buff = rdc_data.Buf;
            int start_pos = 0;
            unsigned char ctype = 0;
            // printf("tran read:\n");
            for (int i = 0; i < rdc_data.len; ++i)
            {
                // printf("%02X ",buff[i]);
                if (buff[i] > 0xf0) 
                {
                    if (buff[i] == 0xff) 
                    {
                        if (ctype) 
                        {
                            ctype = 0;
                            ChannelCmd rdata(buff + start_pos, i - start_pos + 1);
                            ReadDatas->add(rdata);
                            start_pos = i + 1;
                        }
                    }
                    else {
                        ctype = buff[i];
                        start_pos = i;
                    }
                }
            }
            // printf("\n");
            buff = NULL;
            if (start_pos < rdc_data.len)
            {
                RDClient _newrd(rdc_data.Buf + start_pos, rdc_data.len - start_pos);
                rdc_data = _newrd;
            }
            else {
                rdc_data.len = 0;
            }
        }
        //数据帧解析
        while (ReadDatas->getFirst(rddata))
        {
            unsigned char * pBuf = new unsigned char[rddata.len];
            int nLen = pyfree::uncode(rddata.Buf, rddata.len, pBuf);//反序列化处理
            this->AddFrame(pBuf, nLen);
            delete[] pBuf;
            pBuf = NULL;
            ReadDatas->removeFirst();
        }
    }
    break;
    case 2:
    {
        //直接读取,不用做分帧处理,ACSII字段
        char buf[256] = { 0 };
        int len = ptr_client->Read(buf, 256);
        if (len > 0) 
        {
            ChannelCmd rdata((unsigned char*)buf, len);
            ReadDatas->add(rdata);
        }
        //数据帧解析
        if (ReadDatas->getFirst(rddata))
        {
            this->AddFrame(rddata.Buf, rddata.len);
            ReadDatas->removeFirst();
        }
    }
    break;
    default:
        CLogger::createInstance()->Log(MsgError,
            "Exception for Reading and Parsing is undef NetType(%d),[%s %s %d]!"
            , netargs.type
            , __FILE__, __FUNCTION__, __LINE__);
        break;
    }
}

void NetTChannel::wtite()
{
    unsigned char buf[512] = { 0 };
    int len = this->getBuffer(buf);
    if (len < 0 && (heartBeatWrite+10)<static_cast<unsigned int>(time(NULL))) 
    {
        len = this->getHeartBeatBuffer(buf);
    }
    if (len > 0) {
        switch (netargs.type)
        {
        case 1:
        {
            int cacheLen = 2 * len + 1;
            unsigned char* _buf = new unsigned char[cacheLen];
            memset(_buf, 0, cacheLen);
            int nLen = pyfree::code(buf, len, _buf);//序列化处理
            // printf("tran:\n");
            // for (int j = 0; j < nLen; j++) {
            //     printf("%02X", static_cast<unsigned char>(_buf[j]));
            // }
            // printf("\n");
            int ret = ptr_client->Write((const char*)_buf, nLen);
            if (ret != nLen) {
                CLogger::createInstance()->Log(MsgInfo,
                    "send point data: %d, buf %d. [%s %s %d]"
                    , nLen, ret
                    , __FILE__, __FUNCTION__, __LINE__);
            }
            else {
                heartBeatWrite = static_cast<unsigned int>(time(NULL));
            }
            delete[] _buf;
            _buf = NULL;
        }
        break;
        case 2:
        {
            int ret = ptr_client->Write((const char*)buf, len);
            if (ret != len) {
                CLogger::createInstance()->Log(MsgInfo,
                    "send point data: %d, buf %d. [%s %s %d]"
                    , len, ret
                    , __FILE__, __FUNCTION__, __LINE__);
            }
            else {
                heartBeatWrite = static_cast<unsigned int>(time(NULL));
            }
        }
        break;
        default:
            CLogger::createInstance()->Log(MsgError,
                "Exception for Write data and unkown NetType(%d),[%s %s %d]!"
                , netargs.type
                , __FILE__, __FUNCTION__, __LINE__);
            break;
        }

    }
}